﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace LiuQiuRong.Chat.Utilities.Crypto
{
    public class Encryption
    {
        /// <summary>
        /// 默认密钥向量
        /// </summary>
        private static readonly byte[] Keys = { 0x45, 0x34, 0xcd, 0xab, 0x90, 0xef, 0x23, 0x89 };

        /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string EncryptDES(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// AES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string EncryptAES(string encryptString, string encryptKey)
        {
            try
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);

                AesManaged aes = new AesManaged();
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(encryptKey, Keys);
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
                ICryptoTransform encryptTransform = aes.CreateEncryptor();

                // 加密后的输出流   
                MemoryStream encryptStream = new MemoryStream();

                // 将加密后的目标流（encryptStream）与加密转换（encryptTransform）相连接   
                CryptoStream encryptor = new CryptoStream(encryptStream, encryptTransform, CryptoStreamMode.Write);

                // 将一个字节序列写入当前 CryptoStream （完成加密的过程）   
                encryptor.Write(inputByteArray, 0, inputByteArray.Length);
                encryptor.Close();

                // 将加密后所得到的流转换成字节数组，再用Base64编码将其转换为字符串   
                return System.Convert.ToBase64String(encryptStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// SHA-1加密
        /// </summary>
        /// <param name="passwordString">密码</param>
        /// <returns>>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string SHA1(string passwordString)
        {
            try
            {
                SHA1 sha1 = new SHA1Managed();
                //生成8位密钥值
                byte[] password = sha1.ComputeHash(Encoding.UTF8.GetBytes(passwordString));
                return System.Convert.ToBase64String(password);
            }
            catch
            {
                return passwordString;
            }
        }

        /// <summary>
        /// SHA-1校验密码
        /// </summary>
        /// <param name="encryptString">密文</param>
        /// <param name="passwordString">源码</param>
        /// <returns>成功：true，失败:false</returns>
        public static bool CheckSHA1(string encryptString, string passwordString)
        {
            bool ret = false;
            try
            {
                SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
                byte[] saltValue = Encoding.UTF8.GetBytes(encryptString.Substring(encryptString.Length - 8, 8));
                byte[] unsaltedPassword = sha1.ComputeHash(Encoding.UTF8.GetBytes(passwordString));
                byte[] rawSalted = new byte[unsaltedPassword.Length + saltValue.Length];
                unsaltedPassword.CopyTo(rawSalted, 0);
                saltValue.CopyTo(rawSalted, unsaltedPassword.Length);
                byte[] saltedPassword = sha1.ComputeHash(rawSalted);
                byte[] dbPassword = new byte[saltedPassword.Length + saltValue.Length];
                saltedPassword.CopyTo(dbPassword, 0);
                saltValue.CopyTo(dbPassword, saltedPassword.Length);
                if (Convert.ToBase64String(dbPassword) == encryptString)
                    ret = true;
            }
            catch
            {
            }
            return ret;
        }

        public static string GetMD5HashFromString(string str)
        {
            var md5 = new MD5CryptoServiceProvider();
            byte[] bytValue, bytHash;
            bytValue = Encoding.UTF8.GetBytes(str);
            bytHash = md5.ComputeHash(bytValue);
            md5.Clear();
            var sTemp = "";
            for (int i = 0; i < bytHash.Length; i++)
            {
                sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
            }
            return sTemp.ToUpper();
        }
    }
}
